﻿using System.Collections.Generic;
using System.Linq;
using ClientResource.Scripts.Core;
using UnityEngine;

namespace Pisces
{
	/**
	 * 抽象的特效模块
     * created by wangqiang
    **/
	public class EffectModule : AbstractMonoSingletonModule<EffectModule>, InterfaceEntityLiftcycle
	{
		/// <summary>
		/// 正在加载的粒子map
		/// key: 特效id, value: 特效对象
		/// </summary>
		private Dictionary<int, AbstractEffect> loadingEffectDic;
		
		/// <summary>
		/// 正在运行的粒子map
		/// key: 特效id, value: 特效对象
		/// </summary>
		private Dictionary<int, AbstractEffect> runningEffectDic;

		/// <summary>
		/// 粒子自增id
		/// </summary>
		private int incrementID;

		public override void onInit()
		{
			base.onInit();

			incrementID = 1;
			loadingEffectDic = new Dictionary<int, AbstractEffect>();
			runningEffectDic = new Dictionary<int, AbstractEffect>();
		}

		public override void onUpdate(float deltaTime)
		{
			base.onUpdate(deltaTime);
			
			// 先遍历运行中的，以免出现update两次的情况,在loaded之前状态被destroy的，需要在下一帧移除
			for (int i = 0; i < runningEffectDic.Count;)
			{
				KeyValuePair<int,AbstractEffect> keyValuePair = runningEffectDic.ElementAt(i);
				keyValuePair.Value.onUpdate(deltaTime);
				
				if (keyValuePair.Value == null)
				{
					keyValuePair.Value.onDestroy();
					runningEffectDic.Remove(keyValuePair.Key);
				}
				else
				{
					i++;
				}
			}

			for (int i = 0; i < loadingEffectDic.Count;)
			{
				KeyValuePair<int,AbstractEffect> keyValuePair = loadingEffectDic.ElementAt(i);
				
				keyValuePair.Value.onUpdate(deltaTime);
				
				if (keyValuePair.Value.EffectStatus == EffectStatus.LOADED ||
				    keyValuePair.Value.EffectStatus == EffectStatus.PLAYING)
				{
					runningEffectDic.Add(keyValuePair.Key, keyValuePair.Value);
					loadingEffectDic.Remove(keyValuePair.Key);
				}
				else if (keyValuePair.Value.EffectStatus == EffectStatus.DESTROY)
				{
					keyValuePair.Value.onDestroy();
					loadingEffectDic.Remove(keyValuePair.Key);
				}
				else
				{
					i++;
				}
			}

			
		}

		/// <summary>
		/// 添加一个特效
		/// </summary>
		/// <param name="prefabName"></param>
		/// <param name="parent"></param>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		public int addEffect<T>(string prefabName, GameObject parent) where T : AbstractEffect,new()
		{
			if (incrementID == int.MaxValue)
			{
				for (int i = 0; i < int.MaxValue; i++)
				{
					if (loadingEffectDic.ContainsKey(i))
					{
						continue;
					}
					else
					{
						incrementID = i;
						break;
					}
				}
			}

			if (incrementID == int.MaxValue)
			{
				PiscesLog.error($"特效id用完了, 特效:{prefabName}创建失败");
				return (int)CoreErrorCode.PARTICLE_ID_USE_UP;
			}
			
			AbstractEffect effect = gameObject.AddComponent<T>();
			effect.ID = incrementID++;
			effect.PrefabName = prefabName;
			effect.Parent = parent;
			effect.onInit();
			
			loadingEffectDic.Add(effect.ID, effect);
			return effect.ID;
		}

		/// <summary>
		/// 移除特效
		/// </summary>
		/// <param name="effectID"></param>
		public void removeEffect(int effectID)
		{
			AbstractEffect effect = loadingEffectDic[effectID];
			if (effect != null)
			{
				effect.EffectStatus = EffectStatus.DESTROY;
				effect.onDestroy();
				
				loadingEffectDic.Remove(effectID);
				return;
			}

			effect = runningEffectDic[effectID];
			if (effect != null)
			{	
				effect.EffectStatus = EffectStatus.DESTROY;
				effect.onDestroy();
				runningEffectDic.Remove(effectID);
				return;
			}
		}
	}
}